#include "i2c.h"

void I2C_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    I2C_InitTypeDef I2C_InitStructure;
    //
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);    // 总线时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);     // I2C1时钟
    GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN; // 选择IO组的端口引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;          // 复用开漏输出(外部I2C总线加上拉电阻)
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(I2C_PORT, &GPIO_InitStructure); // IO组初始化
    //
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;                                // I2C模式
    I2C_InitStructure.I2C_ClockSpeed = I2C_SUBSPEED;                          // 总线时钟速度 50KHz
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;                        // 时钟占空比
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;                               // 主机是否设置应答
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //
    I2C_InitStructure.I2C_OwnAddress1 = I2C_HOSTADDRESS;                      // 主机地址
    I2C_Init(I2C1, &I2C_InitStructure);
    I2C_Cmd(I2C1, ENABLE); // 开启I2C1
}

void I2C_WaitEvent(I2C_TypeDef *I2Cx, uint32_t I2C_EVENT)
{
    uint32_t Timeout;
    Timeout = 10000;
    while (I2C_CheckEvent(I2Cx, I2C_EVENT) != SUCCESS)
    {
        Timeout--;
        if (Timeout == 0)
        {
            break;
        }
    }
}

void I2C_WriteByte(uint8_t SlaveAddr, uint8_t RegAddr, uint8_t b)
{
    I2C_GenerateSTART(I2C1, ENABLE);
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT); // 检测EV5

    I2C_Send7bitAddress(I2C1, SlaveAddr, I2C_Direction_Transmitter); // 发送器件地址(方向=发送)
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); // 检测EV6（发送模式）

    I2C_SendData(I2C1, RegAddr);                             // 发送器件内部寄存器地址
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING); // 检测EV8

    I2C_SendData(I2C1, b);                                  // 发送内容
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED); // 检测EV8_2 最后一个字节

    I2C_GenerateSTOP(I2C1, ENABLE);
}

void I2C_WriteBuffer(uint8_t SlaveAddr, uint8_t RegAddr, uint8_t *pBuf, uint16_t Size)
{
    I2C_GenerateSTART(I2C1, ENABLE);
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT);               // 检测EV5
    I2C_Send7bitAddress(I2C1, SlaveAddr, I2C_Direction_Transmitter); // 发送器件地址
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); // 检测EV6（发送模式）
    I2C_SendData(I2C1, RegAddr);                                     // 发送器件内部寄存器地址
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED);          // 检测EV8
    while (Size--)
    {
        I2C_SendData(I2C1, *pBuf); // 发送内容
        pBuf++;
        I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED); // 检测EV8_2
    }
    I2C_GenerateSTOP(I2C1, ENABLE);
}

uint8_t I2C_ReadByte(uint8_t SlaveAddr, uint8_t RegAddr)
{
    uint8_t result = 0;

    I2C_GenerateSTART(I2C1, ENABLE);
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT); // 检测EV5 主机模式

    I2C_Send7bitAddress(I2C1, SlaveAddr, I2C_Direction_Transmitter); // 发送器件地址(方向=发送)
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); // 检测EV6（主机发送模式）

    I2C_SendData(I2C1, RegAddr); // 发送器件内部寄存器地址
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED);

    I2C_GenerateSTART(I2C1, ENABLE);
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT); // 检测EV5 主机模式

    I2C_Send7bitAddress(I2C1, SlaveAddr, I2C_Direction_Receiver); // 发送器件地址(方向=接收)
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED); // 主机接收模式

    I2C_AcknowledgeConfig(I2C1, DISABLE); // 最后一个数据关闭应答
    I2C_GenerateSTOP(I2C1, ENABLE);       // 停止

    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED); // EV7
    result = I2C_ReceiveData(I2C1);

    I2C_AcknowledgeConfig(I2C1, ENABLE);
    return result;
}

void I2C_ReadBuffer(uint8_t SlaveAddr, uint8_t RegAddr, uint8_t *pBuf, uint16_t Size)
{

    I2C_GenerateSTART(I2C1, ENABLE);
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT); // 检测EV5 主机模式

    I2C_Send7bitAddress(I2C1, SlaveAddr, I2C_Direction_Transmitter); // 发送器件地址
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); // 检测EV6（发送模式）

    I2C_SendData(I2C1, RegAddr); // 发送器件内部寄存器地址
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED);

    I2C_GenerateSTART(I2C1, ENABLE);
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT); // 检测EV5

    I2C_Send7bitAddress(I2C1, SlaveAddr, I2C_Direction_Receiver); // 发送器件地址(方向=接收)
    I2C_WaitEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED); // 主机接收模式

    while (Size)
    {
        if (Size == 1)
        {
            I2C_AcknowledgeConfig(I2C1, DISABLE);
            I2C_GenerateSTOP(I2C1, ENABLE);
        }
        if (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
        {
            *pBuf = I2C_ReceiveData(I2C1);
            pBuf++;
            Size--;
        }
    }
    I2C_AcknowledgeConfig(I2C1, ENABLE);
}
